<template>
  <div>
    <div
      ref="stretchWrapper"
      class="tn-stretch-wrapper tn-flex-box"
      :class="{
        'is-fold': !isExpanded
      }"
      :style="stretchWrapperStyle"
      :fold-direction="foldDirection"
      justify-content="center"
      align-items="center">
      <div
        class="switch-icon-wrapper"
        :style="switchStyle"
        @click="isExpanded = !isExpanded">
        <span class="switch-icon" :direction="switchDirection">
          <slot name="arrow-right-icon" />
          <el-icon
            v-if="!$slots['arrow-right-icon']"
            class="el-icon-d-arrow-right" />
        </span>
      </div>
      <div
        class="tn-stretch-wrapper__slots-wrapper"
        :size="1">
        <!-- :style="{
          display: isExpanded ? 'block' : 'none'
        }" -->
        <slot />
      </div>
    </div>
  </div>
</template>

<script>
  function getValidWidthOrHeight (val) {
    return isFinite(+val) ? `${+val}px` : val
  }

  const stretchWrapperDefaultStyle = {
    width: 'auto',
    height: 'auto',
    transitionDuration: '250ms',
    transitionProperty: 'all'
  }

  export default {
    name: 'TinyStretchWrapper',
    props: {
      width: {
        type: [String, Number],
        default: 'auto'
      },
      height: {
        type: [String, Number],
        default: 'auto'
      },
      switchPostion: {
        type: String,
        default: 'right',
        validator (value) {
          return ['left', 'right', 'top', 'bottom'].includes(value)
        }
      },
      switchExpandedStyle: {
        type: Object,
        default: () => ({})
      }
    },
    data () {
      return {
        isExpanded: true,
        stretchWrapperStyle: {
          width: 'auto',
          height: 'auto'
        },
        slotsWrapperStyle: {}
      }
    },
    computed: {
      isHorizontal () {
        return ['left', 'right'].includes(this.switchPostion)
      },
      isVertical () {
        return ['top', 'bottom'].includes(this.switchPostion)
      },
      switchDirection () {
        // switch 箭头默认向右
        const {
          switchPostion,
          isExpanded
        } = this
        switch (switchPostion) {
          case 'right':
            return ['right', 'left'][Number(isExpanded)]
          case 'left':
            return ['left', 'right'][Number(isExpanded)]
          case 'top':
            return ['bottom', 'top'][Number(isExpanded)]
          case 'bottom':
            return ['top', 'bottom'][Number(isExpanded)]
          default:
            return ''
        }
      },
      foldDirection () {
        return this.getReversePostion(this.switchDirection)
      },
      switchStyle () {
        const {
          switchPostion,
          switchExpandedStyle,
          isExpanded
        } = this
        return {
        ...(
          this.isHorizontal
            ? {
              top: '50%',
              transform: 'translateY(-50%)',
              [switchPostion]: '-30px',
              ...(
                isExpanded
                  ? switchExpandedStyle
                  : {
                    [switchPostion]: '-30px'
                  }
              )
            }
            : {}
        ),
        ...(
          this.isVertical
            ? {
              left: '50%',
              transform: 'translateX(-50%)',
              [switchPostion]: '-30px',
              ...(
                isExpanded
                  ? switchExpandedStyle
                  : {
                    [switchPostion]: 'auto',
                    [this.getReversePostion(switchPostion)]: '-30px'
                  }
              )
            }
            : {}
        )
        }
      }
    },
    watch: {
      width () {
        this.updateWrapperStyle()
      },
      height () {
        this.updateWrapperStyle()
      },
      isExpanded () {
        this.updateWrapperStyle()
      }
    },
    created () {
      this.updateWrapperStyle()
    },
    methods: {
      getReversePostion (direction) {
        switch (direction) {
          case 'right':
            return 'left'
          case 'left':
            return 'right'
          case 'top':
            return 'bottom'
          case 'bottom':
            return 'top'
          default:
            return ''
        }
      },
      updateWrapperStyle () {
        if (this.isExpanded) {
          this.stretchWrapperStyle = {
            ...stretchWrapperDefaultStyle,
            width: getValidWidthOrHeight(this.width),
            height: getValidWidthOrHeight(this.height)
          }
        } else {
          setTimeout(() => {
            const { clientWidth, clientHeight } = this.$refs.stretchWrapper
            this.stretchWrapperStyle = {
              ...stretchWrapperDefaultStyle,
              transitionProperty: 'none',
              borderWidth: 0,
              ...(
                this.isHorizontal
                  ? {
                    width: 0,
                    height: getValidWidthOrHeight(clientHeight),
                    transform: `translateX(${
                      this.switchPostion === 'left' ? getValidWidthOrHeight(clientWidth) : '-100%'
                    })`
                  }
                  : {
                    width: getValidWidthOrHeight(clientWidth),
                    height: 0,
                    transform: `translateY(${
                      this.switchPostion === 'bottom' ? getValidWidthOrHeight(clientHeight) : '-100%'
                    })`
                  }
              )
            }
          }, 300)
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
.tn-stretch-wrapper{
  position: relative;
  transition: all 0.25s ease-in-out;
  &.is-fold {
    &[fold-direction="left"] {
      transform: translateX(-100%);
    }
    &[fold-direction="right"] {
      transform: translateX(100%);
    }
    &[fold-direction="top"] {
      transform: translateY(-100%);
    }
    &[fold-direction="bottom"] {
      transform: translateY(100%);
    }
  }
  &__slots-wrapper{
    overflow: hidden;
    width: 100%;
    height: 100%;
  }
  .switch-icon-wrapper{
    position: absolute;
    z-index: 9999;
    font-size: 25px;
    cursor: pointer;
    transition: all 0.25s ease-in-out;
    .switch-icon{
      display: block;
      // &[direction="right"] {}
      &[direction="left"] {
        transform: rotateY(180deg);
      }
      &[direction="top"] {
        transform: rotate(-90deg);
      }
      &[direction="bottom"] {
        transform: rotate(90deg);
      }
    }
  }
}
</style>
